package cubelabs.nexus.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.opentok.api.OpenTokSDK;
import com.opentok.api.constants.RoleConstants;

import cubelabs.nexus.entity.Event;
import cubelabs.nexus.entity.OpenTokArchive;
import cubelabs.nexus.entity.OpenTokSession;
import cubelabs.nexus.entity.User;
import cubelabs.nexus.service.NexusService;

@Controller
public class OpenTokController {

	@Autowired
	private NexusService nexusService;
	
	@RequestMapping(value = "/sessionPublisher", method = RequestMethod.GET)
	public ModelAndView sessionPublisher(@RequestParam("eventId") Long eventId){
		ModelAndView modelAndView  = new ModelAndView("videoSessionPublisher");
		modelAndView.addObject("eventId",eventId);
		return modelAndView;
	}
	
	@RequestMapping(value = "/sessionSubscriber", method = RequestMethod.GET)
	public ModelAndView sessionSubscriber(@RequestParam("eventId") Long eventId){
		ModelAndView modelAndView  = new ModelAndView("videoSessionSubscriber");
		modelAndView.addObject("eventId",eventId);
		return modelAndView;
	}
	
	
	@RequestMapping(value = "/startSession", method = RequestMethod.GET)
	public @ResponseBody OpenTokSession startSession(@RequestParam("eventId") Long eventId){
		OpenTokSDK openTokSDK = new OpenTokSDK(21313161, "2c819ea062cc6557e618a4de655bcdce9e33d4f4");
		OpenTokSession openTokSession = new OpenTokSession();
		try {
			String sessionId = openTokSDK.create_session().session_id;
			openTokSession.sessionId  = sessionId;
			String token = openTokSDK.generate_token(sessionId);
			openTokSession.token = token;
			Event event = new Event();
			event.id = eventId;
			openTokSession.event = event;
			//openTokSession.event.id = eventId;//Event.findByEventId(eventId);;
			openTokSession.apiKey = 21313161;
			openTokSession.status = "session_started";
			openTokSession.moderatorToken = openTokSDK.generate_token(sessionId, RoleConstants.MODERATOR);
			openTokSession.subscriberToken = openTokSDK.generate_token(sessionId, RoleConstants.SUBSCRIBER);
			openTokSession.publisherToken = openTokSDK.generate_token(sessionId, RoleConstants.PUBLISHER);
			
			nexusService.saveOrUpdateNexusSession(openTokSession);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return openTokSession;
	}
	
	@RequestMapping(value = "/checkSessionStarted", method = RequestMethod.GET)
	public @ResponseBody OpenTokSession checkSessionStarted(@RequestParam("eventId") Long eventId){
		
		OpenTokSession openTokSession = nexusService.findNexusSessionByEventId(eventId);
		
		if(openTokSession != null && !openTokSession.status.equals("session_stopped")){
			openTokSession.apiKey = 21313161;
			return openTokSession;
		}
		return null;
	}
	
	@RequestMapping(value = "/checkToTeachOrLearn", method = RequestMethod.GET)
	public ModelAndView checkToTeachOrLearn(HttpServletRequest request, HttpServletResponse response,
			@RequestParam("eventId") Long eventId){
		User user = (User) request.getSession().getAttribute("user");
		//User user = getLocalUser(session());
		ModelAndView modelAndView = null;
		OpenTokSession openTokSession = nexusService.findNexusSessionByEventId(eventId);
		if(openTokSession != null && openTokSession.status.equals("session_stopped")){
			 modelAndView = new ModelAndView("error");
		}
		
		Event event = nexusService.findByEventId(eventId);
		if(event != null){
			if(event.user.getId() == user.getId()){
				 modelAndView = new ModelAndView("videoSessionPublisher");
				 modelAndView.addObject("eventId", eventId);
			}else{
				 modelAndView = new ModelAndView("videoSessionSubscriber");
				 modelAndView.addObject("eventId", eventId);
			}
		}else{
			modelAndView = new ModelAndView("error");
		}
		return modelAndView;
	}
	
	@RequestMapping(value="/disconnectSession", method = RequestMethod.GET)
	public ModelAndView disconnectSession(@RequestParam("eventId") Long eventId){
		/*OpenTokSession openTokSession = OpenTokSession.findByEventId(eventId);
		openTokSession.status = "session_stopped";
		openTokSession.update();*/
		//return redirect(controllers.routes.Calendar.list());
		OpenTokSession openTokSession = nexusService.findNexusSessionByEventId(eventId);
		openTokSession.status = "session_stopped";
		nexusService.saveOrUpdateNexusSession(openTokSession);
		ModelAndView modelAndView = new ModelAndView("list");
		return modelAndView;
	}
	
	@RequestMapping(value="/saveArchive", method = RequestMethod.GET)
	public ModelAndView saveArchive(@RequestParam("sessionId") Long sessionId,@RequestParam("archiveId") String archiveId){
		OpenTokArchive archive = new OpenTokArchive();
		OpenTokSession openTokSession = nexusService.findNexusSessionById(sessionId);
		
		if(openTokSession.event != null){
			archive.eventName = openTokSession.event.title;
			archive.event = openTokSession.event;
		}
		archive.archiveId = archiveId;
		archive.openTokSession = openTokSession;
		archive.status = "open";
		
		nexusService.saveOrUpdateNexusArchive(archive);
		ModelAndView modelAndView = new ModelAndView("list");
		
		//modelAndView.addObject("events",events);
		return modelAndView;//redirect(controllers.routes.Calendar.list());
	}
	
	@RequestMapping(value="/renderArchive", method = RequestMethod.GET)
	public ModelAndView renderLoadArchive(@RequestParam("eventId") Long eventId){
		OpenTokArchive openTokArchive = nexusService.findNexusArchiveByEventId(eventId);
		ModelAndView modelAndView = new ModelAndView("videoSessionArchiver");
		modelAndView.addObject("openTokArchive", openTokArchive);
		return modelAndView;
	}
	
	@RequestMapping(value="/archivedVideos", method = RequestMethod.GET)
	public ModelAndView renderArchivedVideosList(@RequestParam("eventId") Long eventId){
		List<OpenTokArchive> openTokArchiveList = nexusService.findAllNexusArchiveByStatus("closed");
		ModelAndView modelAndView = new ModelAndView("archiveList");
		modelAndView.addObject("archivedEvents", openTokArchiveList);
        return modelAndView;
	}
	
	@RequestMapping(value="/updateArchiveStatus", method = RequestMethod.GET)
	public ModelAndView updateArchiveStatus(@RequestParam("archiveId") String archiveId,
			@RequestParam("status") String status){
		OpenTokArchive openTokArchive = nexusService.findNexusArchiveById(archiveId);
		if(openTokArchive != null){
			openTokArchive.status = status;
			nexusService.saveOrUpdateNexusArchive(openTokArchive);
		}
		ModelAndView modelAndView = new ModelAndView("statusSuccess");
		modelAndView.addObject("Message","success");
		return modelAndView;
	}

}
